package com.suning.sawp.service.impl.task;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import com.suning.framework.dal.client.DalClient;
import com.suning.sawp.dto.mainpush.ClerkTaskRespMan;
import com.suning.sawp.po.mainpush.MainPushTask;
import com.suning.sawp.po.mainpush.MainPushTask.AssignStatusConstants;
import com.suning.sawp.po.mainpush.MainPushTask.CommodityStatusConstants;
import com.suning.sawp.po.mainpush.MainPushTask.TaskStatusConstants;
import com.suning.sawp.po.mainpush.StoreCommodityTask;
import com.suning.sawp.po.mainpush.TaskClerk;
import com.suning.sawp.po.mainpush.TaskStore;
import com.suning.sawp.service.task.dto.StaffTaskComm;
import com.suning.sawp.service.task.dto.StoreTaskComm;
import com.suning.sawp.service.task.dto.StoreTaskDetail;

/**
 * 门店任务服务类<br/>
 * 
 * 门店下发任务给店员
 * 
 * @author 13071602
 *
 */
@Service
public class StoreTaskService {

    @Autowired
    DalClient dalClient;

    /**
     * 
     * 查询任务详情
     * 
     * @see sqlMap_StoreTask.xml
     * 
     * @param taskNo 门店任务编号 StoreCommodityTask
     */
    public StoreTaskDetail queryTaskDetail(Long taskNo) {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("taskNo", taskNo);

        // 查询任务详情
        StoreTaskDetail storeTaskDetail = dalClient.queryForObject("StoreTask.queryTaskDetail", paramMap,
                StoreTaskDetail.class);
        final Map<String, String> statusMap = Maps.newHashMap();
        // 分类筛选任务状态
        statusMap.put(MainPushTask.CommodityStatusConstants.NEW, "add");
        statusMap.put(MainPushTask.CommodityStatusConstants.MODIFIED, "update");
        statusMap.put(MainPushTask.CommodityStatusConstants.DEL_NO_READ, "delete");
        paramMap.put("commStatus", Sets.newHashSet(statusMap.keySet()));
        // 查询任务商品列表
        List<StoreCommodityTask> storeCommodityTasks = dalClient.queryForList("StoreTask.queryTaskCommStatus", paramMap,
                StoreCommodityTask.class);

        // fill DTO
        storeTaskDetail
                .setCommNames(Multimaps.asMap(Multimaps.transformValues(MultimapBuilder.treeKeys().linkedListValues()
                        .build(Multimaps.index(storeCommodityTasks, new Function<StoreCommodityTask, String>() {
                            @Override
                            public String apply(StoreCommodityTask input) {
                                return statusMap.get(input.getCommStatus());
                            }
                        })), new Function<StoreCommodityTask, String>() {
                            @Override
                            public String apply(StoreCommodityTask input) {
                                return input.getCommName();
                            }
                        })));
        return storeTaskDetail;
    }

    /**
     * 展示门店任务商品列表以及分配详情(已完成台数/目标台数)
     * 
     * @see sqlMap_StoreTask.xml
     * 
     * @param taskNo 门店任务编号
     * @return 萌点任务分配
     */
    public List<StoreTaskComm> queryTaskComm(Long taskNo) {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("taskNo", taskNo);
        List<StoreTaskComm> taskComms = dalClient.queryForList("StoreTask.queryTaskComms", paramMap,
                StoreTaskComm.class);
        return taskComms;
    }

    /**
     * 分配任务
     */
    @Transactional
    public void bulkAssginTask(Long taskNo, Integer commClassifyCode, List<ClerkTaskRespMan> commTasks) {
        deleteAssginCommTask(taskNo, commClassifyCode);
        // 挨个分配任务
        for (ClerkTaskRespMan respMan : commTasks) {
            assginTask(taskNo, commClassifyCode, respMan.getStaffId(), respMan.getDestNum(), respMan.getStaffName());
        }
        // 同步分配状态【门店商品任务状态、门店任务状态】
        syncAssignStatus(taskNo, commClassifyCode);
    }

    /**
     * 把该门店任务已分配给所有店员商品置为【删除未读】（排除删除已读）的
     */
    private void deleteAssginCommTask(Long taskNo, Integer commClassifyCode) {
        Map<String, Object> commParam = Maps.newHashMap();
        commParam.put("commClassifyCode", commClassifyCode);
        commParam.put("taskNo", taskNo);
        commParam.put("commStatus", MainPushTask.CommodityStatusConstants.DEL_NO_READ);
        commParam.put("excludeCommStatus", MainPushTask.CommodityStatusConstants.DEL_READ);
        commParam.put("destNum", 0);
        dalClient.execute("StoreTask.bulkAssginCommTask", commParam);
    }

    /**
     * 分配任务下的商品给店员
     * 
     * @param taskStore 门店任务
     * @param comm 任务商品信息
     * @param staffId 员工工号
     * @param destNum 目标数量
     * @param staffName 员工工号
     * 
     * @see sqlMap_StoreTask.xml
     */
    private void assginTask(Long taskNo, Integer commClassifyCode, String staffId, Integer destNum, String staffName) {

        Map<String, Object> commParam = Maps.newHashMap();
        commParam.put("commClassifyCode", commClassifyCode);
        commParam.put("taskNo", taskNo);

        // 查询需要分配给店员的商品详情
        StoreCommodityTask commodityTask = dalClient.queryForObject("StoreTask.queryTaskComm", commParam,
                StoreCommodityTask.class);
        Assert.notNull(commodityTask, String.format("%s of %s 不存在，无法分配", commClassifyCode, taskNo));

        // 覆盖任务表，返回店员任务编号
        TaskStore taskStore = new TaskStore();
        taskStore.setTaskNo(taskNo);
        taskStore = dalClient.find(TaskStore.class, taskStore);
        Long taskNoOfStaff = upsertStaffTask(taskStore, staffId, staffName);

        // 更新任务商品表
        Map<String, Object> paramMap = Maps.newHashMap();

        // 新建场景下的状态
        paramMap.put("commStatus_N", MainPushTask.CommodityStatusConstants.NEW);
        // 修改场景的下的状态值
        paramMap.put("commStatus_U", MainPushTask.CommodityStatusConstants.MODIFIED);

        paramMap.put("commClassifyCode", commodityTask.getCommClassifyCode());
        paramMap.put("taskNo", taskNoOfStaff);
        paramMap.put("commName", commodityTask.getCommName());
        paramMap.put("destNum", destNum);
        paramMap.put("categoryCode", commodityTask.getCategoryCode());
        paramMap.put("commType", commodityTask.getCommType());
        paramMap.put("commCodes", commodityTask.getCommCodes());
        dalClient.execute("StoreTask.upsertCommTaskClerk", paramMap);

    }

    /**
     * 查询门店任务商品的各个店员的分配状态
     * 
     * @param taskNo 门店任务编码
     * @param uniCode 商品归类码
     * 
     * @see sqlMap_StoreTask.xml
     */
    public List<StaffTaskComm> queryStaffTaskByUNICode(Long taskNo, Integer commClassifyCode) {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("taskNo", taskNo);
        paramMap.put("commClassifyCode", commClassifyCode);
        paramMap.put("excludeStatus", Sets.newHashSet(TaskStatusConstants.DEL_READ, TaskStatusConstants.IS_DELETE));
        paramMap.put("excludeCommStatus", Sets.newHashSet(CommodityStatusConstants.DEL_READ, CommodityStatusConstants.IS_DELETE));
        List<StaffTaskComm> comms = dalClient.queryForList("StoreTask.queryStaffTaskByUNICode", paramMap,
                StaffTaskComm.class);
        return comms;
    }

    /**
     *
     * 
     * 覆盖更新店员表信息
     * 
     * @param 父级门店任务
     * @see sqlMap_StoreTask.xml
     */
    private Long upsertStaffTask(TaskStore taskStore, String staffId, String staffName) {
        // sqlMap_StoreTask.xml
        // :taskTopic,:startTime,:categoryCode,:orgCode,:endTime
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("taskStatus", taskStore.getTaskStatus());
        paramMap.put("parTaskNo", taskStore.getTaskNo());
        paramMap.put("taskTopic", taskStore.getTaskTopic());
        paramMap.put("startTime", taskStore.getStartTime());
        paramMap.put("categoryCode", taskStore.getCategoryCode());
        paramMap.put("orgCode", taskStore.getOrgCode());
        paramMap.put("endTime", taskStore.getEndTime());
        paramMap.put("taskRespManCode", staffId);
        paramMap.put("taskPespManName", staffName);
        paramMap.put("categoryName", taskStore.getCategoryName());
        dalClient.execute("StoreTask.upsertStaffTask", paramMap);
        return dalClient.queryForObject("StoreTask.queryTaskClerk", paramMap, TaskClerk.class).getTaskNo();
    }

    /**
     * 同步分配状态
     * 
     * @param taskNo
     * @param commClassifyCode
     */
    private void syncAssignStatus(Long taskNo, Integer commClassifyCode) {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("taskNo", taskNo);
        paramMap.put("commClassifyCode", commClassifyCode);
        paramMap.put("assignStatus", AssignStatusConstants.ASSIGNED);
        // 同步门店商品的分配状态(比较已分配台数和目标台数)
        dalClient.execute("StoreTask.syncStoreCommAssignStatus", paramMap);
        // 同步 如果商品的分配状态全部已分配，则门店任务任务已分配
        dalClient.execute("StoreTask.syncStoreTaskAssignStatus", paramMap);
        paramMap.put("commStatus",
                Sets.newHashSet(MainPushTask.CommodityStatusConstants.IS_DELETE, 
                        CommodityStatusConstants.DEL_NO_READ,CommodityStatusConstants.DEL_READ));
        paramMap.put("taskStatus", TaskStatusConstants.IS_DELETE);
        paramMap.put("excludeTaskStatus", TaskStatusConstants.DEL_READ);
        // 同步店员商品状态到店员任务状态 （如果店员所有任务商品均为删除，那么任务状态改为删除未阅、排除已阅的）
        dalClient.execute("StoreTask.syncClerk_commStatus2taskStatus", paramMap);
    }

}
